package com.motu.monstercity.server.game.timedtask;

import com.motu.monstercity.server.game.logic.FightManager;
import com.motu.monstercity.server.game.logic.RankActManager;
import com.motu.monstercity.server.game.logic.UnionScuffleManager;
import com.motu.monstercity.server.game.logic.WorldBossManager;
import com.motu.vertx.module.utility.threadpool.DBLogManager;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class GameTimeTask implements Runnable, Delayed {
	public final static Logger logger = LoggerFactory.getLogger(GameTimeTask.class);
	private int taskId;
	private long time;
	private String methodName;

	public int getTaskId() {
		return taskId;
	}

	public long getTime() {
		return time;
	}

	public GameTimeTask(int taskId, long time, String methodName) {
		this.taskId = taskId;
		this.time = time;
		this.methodName = methodName;
	}

	@Override
	public void run() {
		// 发送给WorkVerticle执行定时任务
		JsonObject obj = new JsonObject();
		obj.put("taskid", taskId);
		obj.put("time", time);
		obj.put("method", methodName);
		TimedTaskManager.sendWorkTask(TimeTaskCmd.WORK_GAME_TIME_TASK, obj);

		// 添加下次定时任务
		addNextTask(taskId);
	}


	@Override
	public long getDelay(TimeUnit unit) {
		return unit.convert(time - TimeUtils.getCurTime(), TimeUnit.SECONDS);
	}

	@Override
	public int compareTo(Delayed o) {
		GameTimeTask that = (GameTimeTask) o;
		return Long.compare(time, that.time);
	}

	/**
	 * 添加下次定时任务
	 *
	 * @param taskId 任务id
	 */
	public static void addNextTask(int taskId) {
		TimeTaskConfig timeTaskConfig = DelayQueueManager.getTimetaskconfig(taskId);
		if (timeTaskConfig == null) {
			return;
		}
		long nextTime = timeTaskConfig.getNextTime();
		Promise<Object> promise = Promise.promise();
		DelayQueueManager.updateTimetaskNextTime(taskId, nextTime, promise);
		promise.future().onComplete(handler -> {
			if (handler.failed()) {
				String errMsg = "##addNextTask error: " + Tool.getException(handler.cause());
				logger.error(errMsg);
				DBLogManager.addServerCrashLog(0, errMsg);
			}
			logger.info("addTimeTaskQueue taskId = " + taskId + " nextTime = " + nextTime + " methodName = " + timeTaskConfig.getMethod());
			DelayQueueManager.addTimeTaskQueue(new GameTimeTask(taskId, nextTime, timeTaskConfig.getMethod()));// 把下个时间点执行的任务放到队列
		});

	}

	/**
	 * 执行具体的定时任务逻辑（WorkVerticle）
	 *
	 * @param jsonObject
	 */
	public static void runGameTimeTask(JsonObject jsonObject) {
		int taskId = jsonObject.getInteger("taskid");
		long time = jsonObject.getLong("time");
		String methodName = jsonObject.getString("method");

		try {
			logger.info("runGameTimeTask taskId = " + taskId + " time = " + time + " methodName = " + methodName);
			Method method = GameTimeTask.class.getMethod(methodName);// 反射调用,正式执行定时任务
			method.invoke(null);
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("##runGameTimeTask error: " + errMsg);
			DBLogManager.addServerCrashLog(0, errMsg);
		}
	}

	/*****************************************以下定义定时任务方法，需要在WorkVerticle中执行************************************************/


	// 每日0点执行的任务
	public static void runDayCloseLogic() {
		logger.info("###runDayCloseLogic !!!");
//		UnionScuffleManager.clearUnionScuffleReport(); // 清空联盟战报和公告
	}

	// 每周日23:50执行的任务,周榜结算
	public static void runWeekRankCloseLogic() {
		logger.info("###runWeekRankCloseLogic!!!");
		try {
			FightManager.closeSnatchRank();// 设置物资争夺排行榜的过期时间
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###runWeekRankCloseLogic error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}

	public static void doRankActReward() { // 本服冲榜活动结算
		logger.info("###doRankActReward!!!");
		try {
			RankActManager.doRankActReward();
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###doRankActReward error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}

	public static void matchCrossRankAct() { // 跨服冲榜活动分组
		logger.info("###matchCrossRankAct!!!");
		try {
			RankActManager.matchCrossRankAct();
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###matchCrossRankAct error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}
	public static void runCrossRankReward() { // 跨服冲榜活动结算
		logger.info("###runCrossRankReward!!!");
		try {
			RankActManager.runCrossRankReward();
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###runCrossRankReward error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}


	public static void runUnionScuffleReward() { // 联盟战结算
		logger.info("###runUnionScuffleReward!!!");
		try {
			UnionScuffleManager.closeMatchRank();
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###runUnionScuffleReward error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}

	public static void runUnionScuffleClear() {
		logger.info("###runUnionScuffleClear!!!");
		UnionScuffleManager.clearRankData();
	}

	public static void runWorldBossSettle() { // 世界Boss结算
		logger.info("###runWorldBossSettle!!!");
		try {
			WorldBossManager.sendWorldBossRankReward();  // 进行发奖
		} catch (Exception e) {
			String errMsg = Tool.getException(e);
			logger.error("###runWorldBossSettle error:" + errMsg);
			DBLogManager.addServerCrashLog(999999, errMsg);
		}
	}

}
